/**
 * 
 */
package com.orcwar.gui.animations;

import java.util.List;

import android.graphics.Canvas;
import android.graphics.Point;

import com.orcwar.engine.OWTile;
import com.orcwar.engine.OWUnit;
import com.orcwar.engine.animation.AnimatedSprite;
import com.orcwar.engine.units.OWTireurDeLoin;
import com.orcwar.enums.DirectionEnum;
import com.orcwar.enums.SpriteEnum;
import com.orcwar.gui.OWGUI;

/**
 * Handle the movement of a unit through a list of tiles.
 * @author Callil
 *
 */
public class OWAttackAnimator {
	
	/** The game. */
	private OWGUI gui;
	
	/** The unit to move. */
	private OWUnit unit;
	
	/** The targeted tile. */
	private OWTile tile;
	
	private List<OWUnit> attackedUnits;
	
	private boolean success;
	private DirectionEnum orientation;
	
	//Move attributes
	private boolean moveToTarget;
	private int projectileSpeed;
	private Point destinationCoordinates;
	private boolean moveRight;
	private boolean moveDown;
	private boolean destinationXReached;
	private boolean destinationYReached;
	
	/** Whether the movement is over. */
	private boolean done = false;
	
	private AnimatedSprite anim;

	
	public OWAttackAnimator(OWGUI gui, OWUnit unit, OWTile tile, List<OWUnit> attackedUnits, boolean success) {
		this.gui = gui;
		this.unit = unit;
		this.setAttackedUnits(attackedUnits);
		this.tile = tile;
		this.setSuccess(success);
		
		if (unit instanceof OWTireurDeLoin) {
			anim = new AnimatedSprite(SpriteEnum.ATTACK_TIREUR);
			anim.setX( (int) (unit.getTile().getPosition().centerX() - anim.getWidth()/2) );
			anim.setY( (int) (unit.getTile().getPosition().centerY() - anim.getHeight()/2) );
			initProjectile(unit, tile);
			
			moveToTarget = true;
		} else {
			anim = new AnimatedSprite(SpriteEnum.ATTACK_FLEAUTEUR);
			anim.setX( (int) (tile.getPosition().centerX() - anim.getWidth()/2) );
			anim.setY( (int) (tile.getPosition().centerY() - anim.getHeight()/2) );
			moveToTarget = false;
		}
		

		anim.play( "attack", false, true);
		
		orientation = unit.getTile().directionToTile(tile);
		
		//Disable UI actions during the animation
		gui.setActionsBlocked(true);
//		//Hide the highlight of tiles
//		gui.clearHighlights();
//		//Unselect the unit
//		gui.getController().deselectUnit();
	}


	/**
	 * @param unit
	 * @param tile
	 */
	private void initProjectile(OWUnit unit, OWTile tile) {
		destinationCoordinates = new Point((int) (tile.getPosition().centerX() - anim.getWidth()/2),
				(int) (tile.getPosition().centerY() - anim.getHeight()/2));
		
		if (destinationCoordinates.x > anim.getX()) moveRight = true;
		if (destinationCoordinates.y > anim.getY()) moveDown = true;
		
		if (Math.abs(unit.getTile().getX() - tile.getX()) == 4 || Math.abs(unit.getTile().getY() - tile.getY()) == 4) {
			projectileSpeed = 8;
		} else if (Math.abs(unit.getTile().getX() - tile.getX()) == 3 || Math.abs(unit.getTile().getY() - tile.getY()) == 3) {
			projectileSpeed = 6;
		} else if (Math.abs(unit.getTile().getX() - tile.getX()) == 2 || Math.abs(unit.getTile().getY() - tile.getY()) == 2) {
			projectileSpeed = 4;
		} else if (Math.abs(unit.getTile().getX() - tile.getX()) == 1 || Math.abs(unit.getTile().getY() - tile.getY()) == 1) {
			projectileSpeed = 2;
		}
	}

	
	/**
	 * Update.
	 * @param gameDuration the game duration
	 */
	public void update(long gameDuration) {

		//Check whether the anim is over
		if (!moveToTarget && anim.isAnimationFinished() ||
				(moveToTarget && destinationXReached && destinationYReached)) {
			finish();
			return;
		}
		
		//Move the sprite if needed
		if (moveToTarget) {
			
			if (!destinationXReached) {
				if (moveRight) {
					if (destinationCoordinates.x > anim.getX()) {
						anim.setX(anim.getX() + projectileSpeed);
					} else {
						destinationXReached = true;
					}
				} else {
					if (destinationCoordinates.x < anim.getX()) {
						anim.setX(anim.getX() - projectileSpeed);
					} else {
						destinationXReached = true;
					}
				}
			}
			
			if (!destinationYReached) {
				if (moveDown) {
					if (destinationCoordinates.y > anim.getY()) {
						anim.setY(anim.getY() + projectileSpeed);
					} else {
						destinationYReached = true;
					}
				} else {
					if (destinationCoordinates.y < anim.getY()) {
						anim.setY(anim.getY() - projectileSpeed);
					} else {
						destinationYReached = true;
					}
				}
			}
		}
		
		anim.update(gameDuration);
		
	}
	
	
	/**
	 * Draw the animation's current frame.
	 * @param canvas
	 */
	public void draw(Canvas canvas) {
		anim.draw(canvas, null, orientation);
	}
	
	
	
	/**
	 * Finish the movement.
	 */
	private void finish() {
		//Set the mover as done so that the game will remove it at the next
		//update
		done = true;

		//re enable the UI actions
		gui.setActionsBlocked(false);
	}
	
	/**
	 * @return the done
	 */
	public boolean isDone() {
		return done;
	}
	
	/** @return The unit. */
	public OWUnit getUnit() {
		return unit;
	}


	/**
	 * @return the tile
	 */
	public OWTile getTile() {
		return tile;
	}


	/**
	 * @param tile the tile to set
	 */
	public void setTile(OWTile tile) {
		this.tile = tile;
	}


	/**
	 * @return the attackedUnits
	 */
	public List<OWUnit> getAttackedUnits() {
		return attackedUnits;
	}


	/**
	 * @param attackedUnits the attackedUnits to set
	 */
	public void setAttackedUnits(List<OWUnit> attackedUnits) {
		this.attackedUnits = attackedUnits;
	}


	/**
	 * @return the success
	 */
	public boolean isSuccess() {
		return success;
	}


	/**
	 * @param success the success to set
	 */
	public void setSuccess(boolean success) {
		this.success = success;
	}

}
